﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using DrillOnline.Models;
using DrillOnline.Services;
using DrillOnline.Services.Scenarios;
using WebMatrix.WebData;
namespace DrillOnline.Controllers
{
    [Authorize()]
    public class ManageController : _BaseController
    {
        protected override void OnActionExecuting(ActionExecutingContext filterContext)
        {
            if (!User.Identity.IsAuthenticated || User.Identity.Name != "管理员")
            {
                throw new SiteException("not login or access deny");
            }

            base.OnActionExecuting(filterContext);
        }
        //
        // GET: /Manage/

        public ActionResult Index()
        {
            return Redirect("LoadSubject");
        }

        //GET: /Manage/LoadSubject			senariolist,senarioinfo,loadAndCreateSession
        public ActionResult LoadSubject()
        {
            var cs = GetCurrentSession();
            if (null != cs && cs.Timeline.Status != 0)
            {
                ModelState.AddModelError("DenyLoad", "In playing");
                ViewBag.DenyLoad = true;
                return View();
            }

            var m = UserTenant.DrillSubjects;
            return View(m);
        }
        //POST:	/Manage/LoadSubject			senariolist,senarioinfo,loadAndCreateSession
        [HttpPost]
        public ActionResult LoadSubject(DrillSubject item)
        {
            var cs = GetCurrentSession();
            if (null != cs && cs.Timeline.Status != 0)
            {
                ModelState.AddModelError("DenyLoad", "In playing");
                ViewBag.DenyLoad = true;
                return View();
            }

            //var m = DB.DrillSubjects.Find(item.ID);
            var m = UserTenant.DrillSubjects.FirstOrDefault(s => s.ID == item.ID);
            if (null == m)
            {
                ModelState.AddModelError("DenyLoad", "Subject not subscript");
                ViewBag.DenyLoad = "";
                return View();
            }

            var ns = Services.LoadScenarios(m);
            if (null != ns)
            {
                return Redirect("GroupAccounts");
            }
            else
            {
                //load
                return View(m);
            }
        }


        //GET: POST:	/Manage/GroupAccounts		grouplist,groupinfo,examiner, userlist,
        [HttpGet]
        public ActionResult GroupAccounts()
        {
            var cs = GetCurrentSession();
            if (null == cs || UserTenant.DrillSubjects.Contains(cs.Subject)) { return Redirect("LoadSubject"); }

            return View(cs);
        }
        //POST:	/Manage/GroupAccounts		grouplist,groupinfo,examiner, userlist,
        [HttpPost]
        public ActionResult GroupAccounts(Guid ID, string Examiners, string Actors, string ActorPwd, string ExaminerPwd)
        {
            Random r = new Random();
            var cs = GetCurrentSession();
            if (null == cs || UserTenant.DrillSubjects.Contains(cs.Subject)) { return Redirect("LoadSubject"); }

            var g = cs.ActorGroups.FirstOrDefault(v => v.ID == ID);
            if (g != null)
            {
                //g.Actors.Clear();
                //g.Examiners.Clear();
                ActorPwd = ActorPwd.Trim();
                ExaminerPwd = ExaminerPwd.Trim();
                Actors = Actors.Replace('，', ',');
                Examiners = Examiners.Replace('，', ',');
                g.Actors = Actors.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries).Select(v => new Actor() { Group = g, GroupKey = g.GroupKey, ActorKey = v, Password = string.IsNullOrEmpty(ActorPwd) ? r.Next(1000, 9999).ToString() : ActorPwd }).ToList();
                g.Examiners = Examiners.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries).Select(v => new Actor() { Group = g, GroupKey = g.GroupKey, ActorKey = v, Password = string.IsNullOrEmpty(ExaminerPwd) ? r.Next(100000, 999999).ToString() : ExaminerPwd }).ToList();
            }

            return Redirect("CtrlPanel");
        }

        //GET:			/Manage/PrintAccounts		group-user-password grid for print and split paper by row for users;with examiner
        public ActionResult PrintAccounts()
        {
            var cs = GetCurrentSession();
            if (null == cs || UserTenant.DrillSubjects.Contains(cs.Subject)) { return Redirect("LoadSubject"); }

            return View(cs.ActorGroups);
        }
        //GET:		/Manage/CtrlPanel			eventlist,sessioninfo, playing info,controller,senarioinfo,
        [HttpGet]
        public ActionResult CtrlPanel()
        {
            var cs = GetCurrentSession();
            if (null == cs || UserTenant.DrillSubjects.Contains(cs.Subject)) { return Redirect("LoadSubject"); }

            return View(cs);
        }

        //POST:		/Manage/CtrlPanel			eventlist,sessioninfo, playing info,controller,senarioinfo,
        [HttpPost]
        public ActionResult CtrlPanel(string ctrl)
        {
            var cs = GetCurrentSession();
            if (null == cs || UserTenant.DrillSubjects.Contains(cs.Subject)) { return Redirect("LoadSubject"); }

            List<string> errors = new List<string>();
            if ("ScenariosStart".Equals(ctrl, StringComparison.CurrentCultureIgnoreCase))
            {
                //check cs,must load, has examine,actor...
                if (cs.SceneList == null || cs.SceneList.Count == 0) errors.Add("脚本未载入完成。");
                //if (cs.ActorGroups.Any(v => v.Actors.Count < 0)) errors.Add("部分组未分配人员账号。");
                //if (cs.ActorGroups.Any(v => v.Examiners.Count < 0)) errors.Add("部分组未分配评分员账号。");

                if (!cs.ActorGroups.Any(v => v.Actors.Count > 0)) errors.Add("部分组未分配人员账号。");
                if (!cs.ActorGroups.Any(v => v.Examiners.Count > 0)) errors.Add("部分组未分配评分员账号。");


                TrainingSession ts = new TrainingSession()
                {
                    SubjectID = cs.Subject.ID,
                    TenantID = UserTenant.Id,
                    ID = Guid.NewGuid(),
                    PlayingRate = cs.Subject.PlayingRate,
                    StartTime = DateTime.Now,
                    EndTime = DateTime.Now,
                    Status=0, 
                    StoryBaseTime = cs.Timeline.StoryBaseTime,
                    DrillDescription = cs.Subject.Description,
                    DrillTitle = cs.Subject.Title,
                    SessionKey = cs.SessionKey,
                    SessionName = cs.SessionName
                };
                DB.TrainingSessions.Add(ts);
                DB.SaveChanges();

                cs.Session = ts;
                cs.IsReady = true;
            }
            else if ("ScenariosStop".Equals(ctrl, StringComparison.CurrentCultureIgnoreCase))
            {
                //save session,save user,save messages,save examine
                cs.IsReady = false;
                cs.Timeline.Stop();
                TrainingSession ts = cs.Session;
                ts.Status = 1; ts.StartTime = cs.Timeline.PlayingStartTime; ts.EndTime = DateTime.Now;

                var ms = cs.Messages.Select(v => new TrainningSessionMessage
                {
                    Id = Guid.NewGuid(),
                    FromActor = v.FromActor,
                    FromActor_Group = v.FromActor_Group,
                    Message = v.Content,
                    PlayingOffset = v.PlayingOffset,
                    RealTime = v.RealTime,
                    SotryTime = v.StoryTime,
                    TargetGroup = (v.TargetGroup == null) ? "" : string.Join(",", v.TargetGroup),
                    SessionID=ts.ID,
                    SubjectID=ts.SubjectID,
                    EventID=Guid.Parse(v.TargetEventID)
                });
                DB.TrainningSessionMessages.AddRange(ms);


                DB.SaveChanges();
                
            }
            else if ("StoryPause".Equals(ctrl, StringComparison.CurrentCultureIgnoreCase))
            {
                cs.Timeline.Pause();
            }
            else if ("StoryStop".Equals(ctrl, StringComparison.CurrentCultureIgnoreCase))
            {
                cs.Timeline.Stop();
            }
            else if ("StoryStart".Equals(ctrl, StringComparison.CurrentCultureIgnoreCase))
            {
                cs.Timeline.Start();
            }
            else
            {
                return Json(false);
            }
            //cs.NotifyStatusChange();
            return Json(true);
        }
        //GET:			/Manage/SessionList			sessionlist,->linktoExportSession

        public ActionResult SessionList()
        {
            var m = DB.TrainingSessions;

            return View(m);
        }

        //GET:			/Manage/ExportSession		export
        public ActionResult ExportSession(Guid sessionkey)
        {

            var s = DB.TrainingSessions.Find(sessionkey);
            if (null == s) return null;
            if (!UserTenant.DrillSubjects.Contains(s.DrillSubject))
            {
                return null;
            }
            //export messages all
            //export session info
            //export group examine
            //TODO: export group examine result

            byte[] buffer = DocumentServices.CreateSpreadsheetDocument(new DocumentServices.SheetSource[] { 
                new DocumentServices.SheetSource(){
                    Title="演练基本信息",
                    Headers=new string[]{"名称","开始时间","发生时刻","演练速度"},
                    Rows=new string[][]{new string[]{s.SessionName,s.StartTime.ToString(),s.StoryBaseTime.ToString(),s.PlayingRate.ToString()}}
                },
                new DocumentServices.SheetSource(){
                    Title="演练人员响应记录",
                    Headers="现实时间,发生时刻,震后时间,演练人员,所属组,消息内容".Split(','),
                    Rows=DB.TrainningSessionMessages.ToList().Select(v=>new string[]{
                        v.RealTime.ToString("yyyy-MM-dd HH:mm:ss"), v.SotryTime.ToString("yyyy-MM-dd HH:mm:ss"),
                        TimeSpan.FromSeconds(v.PlayingOffset).ToString(), v.FromActor, v.FromActor_Group, v.Message
                    }).ToArray()
                },
                new DocumentServices.SheetSource(){
                    Title="演练评估记录",
                    Headers=new string[]{"场次","分组名称","事件内容","回答内容","评估人","得分"},
                    Rows=s.TrainningEvaluations.ToList().Select(v=>new string[]{
                       v.SessionName, v.Group, v.EventContent,v.ReplyContent,v.ExaminerName, v.ValuePoint.ToString()
                    }).ToArray()
                },
                new DocumentServices.SheetSource(){
                    Title="演练评估结果",
                    Headers=new string[]{"演练记录名称","分组名称","评估人","无效答案数","合格数","优秀数"},
                    Rows=(from t in s.TrainningEvaluations
                          group t by t.Group into g
                          select new string[]{g.FirstOrDefault().SessionName, g.Key, g.FirstOrDefault().ExaminerName
                              , g.Where(t=>t.ValuePoint==0).Count().ToString()
                              , g.Where(t=>t.ValuePoint==1).Count().ToString()
                              , g.Where(t=>t.ValuePoint==2).Count().ToString()                              
                          }).ToArray()
                    
                }

            });

            return File(buffer, "application/excel", s.SessionName + ".xlsx");

        }



    }
}
